#!/usr/bin/python
# -*- coding: utf-8 -*-

##
 # Copyright 2009 Caio Souza
 # This file is part of Rpyg.
 #
 # Rpyg is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
 # Rpyg is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with Rpyg. If not, see <http://www.gnu.org/licenses/>.
 ##
 
import os
from xml.dom.minidom import parse as XmlParse

import pygame

import rpyg
    
class Tiled2Rpyg:
    
    def __init__ (self, filename, dirname = '.'):
        data = XmlParse (filename)
        
        self.map = data.getElementsByTagName ('map')[0]
        '''Dados sobre o mapa de tiles.'''
                                                
        tileset = self.map.getElementsByTagName ('tileset')[0]
        
        self.firstgid = int (tileset.getAttribute ('firstgid'))
        '''Identificador do primeiro tile do conjunto de tiles.'''
        
        self.tilewidth = int (tileset.getAttribute ('tilewidth'))
        '''Largura do tile do mapa.'''
        
        self.tileheight = int (tileset.getAttribute ('tileheight'))
        '''Altura do tile do mapa.'''
        
        image = tileset.getElementsByTagName ('image')[0]
        image = [dirname] + image.getAttribute ('source').split ('/')
        self.image = os.path.join (*image)
        '''Nome do arquivo com a imagem dos tiles.'''
        
        rect = pygame.image.load (self.image).get_rect ()
        self.line = rect.w // self.tilewidth
        '''NÃºmero de tiles por linha.'''
        
        self.layers = self.map.getElementsByTagName ('layer')
        '''Camadas do mapa.'''
        
        self.width = int (self.layers[0].getAttribute ('width'))
        '''Largura do mapa.'''
        
        self.height = int (self.layers[0].getAttribute ('height'))
        '''Altura do mapa.'''
        
        self._newMatrix ()
        self._createTileStatus ()
        self._createMap ()
    
    def _newMatrix (self):
        '''Cria uma matriz vazia a partir do tamanho do mapa.'''
        
        self.matrix = []
        '''Matrix dos tiles do mapa.'''
        
        for _ in range (self.height):
            row = []
            for _ in range (self.width):
                row.append ([])
            self.matrix.append (row)

    def _createTileStatus (self):
        '''Cria os dicionÃ¡rios de estados dos tiles.'''
        
        self.depth = {}
        '''DicionÃ¡rio com o profundidade dos tiles.'''
        
        self.depth_default = -1
        '''Profundidade padrÃ£o dos tiles.'''
        
        self.blocked = {}
        '''DicionÃ¡rio com os tiles bloqueados.'''
        
        self.blocked_default = False
        '''Estado padrÃ£o dos tiles bloqueados.'''
        
        properties = self.map.getElementsByTagName ('properties')
        if not len (properties): return
        
        properties = properties[0]
        properties = self.map.getElementsByTagName ('property')
        
        for property in properties:
            name = property.getAttribute ('name').lower ()
            value = property.getAttribute ('value')
            
            if name == 'depthdefault': self.depth_default = int (value)
            elif name == 'blockeddefault': self.blocked_default = bool (value)
            else:
                values = value.lower ().split (',')
                name = int (name) - self.firstgid
                
                for value in values:
                    if value == 'top': self.depth[name] = 1;
                    elif value == 'bottom': self.depth[name] = -1;
                    
                    elif value == 'pass': self.blocked[name] = False;
                    elif value == 'block': self.blocked[name] = True;

    def _createMap (self):
        '''Cria o mapa a partir dos dados obtidos.'''
        
        for layer in self.layers:
            data = layer.getElementsByTagName ('data')[0]
            tiles = data.getElementsByTagName ('tile')
            
            i = j = 0
            
            for tile in tiles:
                tile = int (tile.getAttribute ('gid')) - self.firstgid
                
                if tile != -self.firstgid:
                    x = (tile % self.line) * self.tilewidth
                    y = (tile // self.line) * self.tileheight
                    
                    layer_aux = rpyg.Layer (self.image, (x, y, self.tilewidth, self.tileheight))
                    image_aux = rpyg.Image (rpyg.Frame (layer_aux))
                    blocked = self.blocked.get (tile, self.blocked_default)
                    depth = int (self.depth.get (tile, self.depth_default))

                    self.matrix[i][j].append (rpyg.Tile (image_aux, blocked, depth))
                
                j = (j + 1) % len (self.matrix[0])
                if not j: i += 1
          
    def toRpyg (self):
        '''Retorna o mapa no formato Rpyg.'''
        return rpyg.TileMap (self.matrix, self.tilewidth, self.tileheight)
    